
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "type.h"
#include "ccas.h"

error_t ccas_push(string *L1,char c1)
{
    string m1 = (string)malloc(sizeof(node1));
    if (m1 == NULL) return CCA_ERROR;
    memset(m1, 0, sizeof(node1));

    m1->data[0] = c1;
    m1->len=1;
    m1->next=*L1;
    m1->prev=NULL;

    if (*L1 != NULL) (*L1)->prev=m1;
    *L1=m1;

    return CCA_OK;
}

error_t ccas_insert(string *L1, char C1)
{
    if (*L1 == NULL) return ccas_push(L1,C1);
    if ((*L1)->len == CCAS_LENGTH)
        return ccas_push(L1,C1);
    (*L1)->data[(*L1)->len++] = C1;
    return CCA_OK;
}

void ccas_free(string* L1)
{
    if (*L1 == NULL) return;
    if ((*L1)->next!=NULL)
        ccas_free(&(*L1)->next);
    free(*L1); //*L1=NULL;
}

string ccas_tail(string L1)
{
    if (L1 == NULL) return NULL;
    while(L1->next != NULL) L1 = L1->next;
    return L1;
}

string ccas_r()
{
    string m1 = NULL;
    int c;
    while('\n' != (c = getchar()) &&  CCA_OK == ccas_insert(&m1, (char)c));
    if (c == '\n') return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_rs(char* CS1)
{
    string m1 = NULL;
    char *p1 = CS1;
    while('\0' != *p1  &&  ccas_insert(&m1, *(p1++)) == CCA_OK)
    {
        //printf("%c",*p1);
    }
    if (*p1 == '\0') return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_as(string *s1, const char *c1)
{
    const char *p1 = c1;
    while('\0' != *p1  &&  ccas_insert(s1, *(p1++)) == CCA_OK)
    {
        //printf("%c",*p1);
    }
    if (*p1 == '\0') return *s1;
    else {
        ccas_free(s1);
        return NULL;
    }
}

string ccas_rf(char* path)
{
    FILE* f = fopen(path, "r");
    if (!f) return NULL;

    string m1 = NULL;
    int c;
    while( (c=fgetc(f)) != EOF && ccas_insert(&m1, (char)c) == CCA_OK);
    fclose(f);
    if ( c == EOF) return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_rf2(FILE* f1)
{
    string m1 = NULL;
    int c;
    while( (c=fgetc(f1)) != EOF && ccas_insert(&m1, (char)c) == CCA_OK);
    if ( c == EOF) return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

char* ccas_ws(string L1)
{
    if (!L1) return NULL;
    char *cs1 = (char*)malloc(sizeof(char));
    if (!cs1) return NULL;
    *cs1 = '\0';

    L1 = ccas_tail(L1);
    while(L1)
    {
        int lt1 = strlen(cs1);
        cs1 = (char*)realloc(cs1, lt1+1 + L1->len);
        if (cs1 == NULL) return NULL;

        int i=0;
        for (;i < L1->len; ++i){
            //printf("%c",L1->data[i]);
            cs1[lt1+i] = L1->data[i];
        }
        cs1[lt1+i] = '\0';

        L1 = L1->prev;
    }

    return cs1;
}

error_t ccas_wf(string L1, char* Path1)
{
    FILE *f = fopen(Path1, "w");
    if(!f) return CCA_ERROR;

    string l2 = ccas_tail(L1);
    while(l2 != NULL)
    {
        int i=0;
        for (;i < l2->len; ++i)
            fputc(l2->data[i], f);
        l2 = l2->prev;
    }

    fclose(f);
    return CCA_OK;
}